<?php
// require these:
AppCore::using('Dao_Base');
AppCore::using('Exception_Dao');
AppCore::using('Dao_Adaptor_Sqlite');

// also need models...
AppCore::using('Model_Base');
AppCore::using('Model_Commentor_Comment');
AppCore::using('Model_Commentor_User');
AppCore::using('Model_Commentor_Site');
AppCore::using('Interface_Sitecontrol');

/**
 * oxi dao
 * delegates to the adaptor for various things
 * @uses: Dao_Base
 * @author: bruce.li
 */
class Dao_Commentor extends Dao_Base implements Interface_Sitecontrol
{
    /**
     * site id
     */
    protected $_siteId = 0;


    /**
     * constructor
     * @param $options
     * @return void
     */
    public function __construct($options = array())
    {
        // default is using config: db_oxi...
        if (empty($options)) {
            $options = Util_Config::get('db_commentor');
        }

        parent::__construct('sqlite', $options);

    }// end __cosntruct


    /**
     * set site id
     * @param int $id
     */
    public function setSiteId($id)
    {
        $this->_siteId = $id;
        return $this;

    }// end setSiteId


    /**
     * get comments out...
     * just a test...
     */
    public function getComments($start = 0, $limit = 100, $condition = '', $sort = array('created_by' => 'DESC'))
    {
        if (strpos($condition, 'site_id') !== false) {
            throw new Exception('SITE ID is not allowed in condition');
        }

        if (empty($condition)) {
            $condition = 'site_id = ' . $this->_siteId;
        } else {
            $condition .= ' AND site_id = ' . $this->_siteId;
        }
        // fix it here
        $comments = $this->readObjects(new Model_Commentor_Comment, $start, $limit, $condition, $sort);
        return $comments;

    }// end build


    /**
     * get comments per article...
     * @param int $article_id the id
     * @param int $start
     * @param int $end
     * @param array $sort
     * @return array the list of comments
     */
    public function getCommentsByArticleId($article_id, $start = 0, $limit = 100, $sort = array('created_by' => 'DESC'))
    {
        // customized query to speed up the shit...
        $sql = 'SELECT
                    "c".*,
                    "u"."username",
                    "u"."web",
                    "u"."ip"
                FROM
                    "comments" AS "c"
                INNER JOIN
                    "users" AS "u"
                ON
                    "c"."user_id" = "u"."id"
                WHERE
                    "c"."site_id" = ?
                AND
                    "c"."article_id" = ?
                AND
                    "c"."active" = \'Y\'
                AND
                    "u"."active" = \'Y\'

                ' . $this->_getOrderBy($sort) . '
                LIMIT ' . $start . ', ' . $limit . '
                ';
        $bind = array($this->_siteId, $article_id);
        $results = $this->fetchAll($sql, $bind);
        // return $results;
        $users    = array();
        $comments = array();
        if (is_array($results)) {
            foreach ($results as $result) {
                // first user shouldn't repeat itself
                if (!isset($users[$result['user_id']])) {
                    $uData = $result;
                    $uData['id'] = $result['user_id'];
                    $users[$result['user_id']] = new Model_Commentor_User($uData);
                    unset($uData);
                }
                // now... add new comments...
                $comments[$result['id']] = new Model_Commentor_Comment($result);
                $comments[$result['id']]->setUser($users[$result['user_id']]);
            }
        }

        return $comments;

    }// end getCommentsByArticleId


    /**
     * save the comment
     * @param Model_Commentor_Comment $comment the obj
     */
    public function saveComment(Model_Commentor_Comment $comment)
    {
        // first of all, extract user from it...
        $user = $comment->getUser();
        if (!$user instanceof Model_Commentor_User) {
            throw new Exception('User is not valid');
        }

        // otherwise, save it if not in already, based on username...
        $sql = 'SELECT * FROM users WHERE username = ? AND ip = ? LIMIT 1';
        $result = $this->fetchOne($sql, array($user->getUsername(), $user->getIp()));
        if (!empty($result)) {
            // set the id of the site...
            $comment->setUserId($result['id']);
        } else {
            // save it...
            try {
                $id = $this->saveObject($user);
                $comment->setUserId($id);
            } catch (Exception_Dao $e) {
                return array($e->getSql(), $e->getBind());
            }
        }

        // since there's site id...
        $comment->setSiteId($this->_siteId);
        return $this->saveObject($comment);

    }// end saveComment


    /**
     * delete comment
     * @param Model_Commentor_Comment $comment the obj
     * @return bool
     */
    public function deleteComment(Model_Commentor_Comment $comment)
    {
        return $this->deleteObject($comment);

    }// end deleteComment


    /**
     * delete comment by id
     * @param int $id the id
     * @return bool
     */
    public function deleteCommentById($id)
    {
        return $this->_adaptor->delete('comments', 'id = ' . intval($id));

    }// end deleteCommentById

    /*------------------------------ site related ------------------------------------*/

    /**
     * get site by given key
     * @param str $key the auth key
     * @return void
     */
    public function getSiteByKey($key)
    {
        // note that site can not be retrieved directly by id... so use key instead.
        $site = new Model_Commentor_Site;
        $site->flagUpdate(false);
        try {
            return $this->readObject($site, '"key" = ' . $this->quote($key));
        } catch (exception $e) {
            return false;
        }

    }// end getSiteByKey


    /**
     * save the site
     * @param Model_Commentor_Site $site the obj
     */
    public function saveSite(Model_Commentor_Site $site)
    {
        // first, make sure site is not already in...
        if ($site->isNew()) {
            $obj = new Model_Commentor_Site;
            $obj->flagUpdate(false);
            $this->readObject($obj, 'url = ' . $this->quote($site->getUrl()));
            if ($obj->getKey() !== '') {
                // already in!
                return false;
            }
        }
        return $this->saveObject($site);

    }// end saveSite


    /**
     * simple addsite function
     */
    public function addSite($name, $url)
    {
        $site = new Model_Commentor_Site(array(
            'name' => $name,
            'url'  => $url
        ));
        $site->keyGen()->setActive(true);
        return $this->saveSite($site);

    }// end addSite


    /**
     * get all site tokens
     * @return array
     */
    public function getTokens()
    {
        // this is one query that is always cached...
        $sql = 'SELECT "id", "key" FROM "sites" WHERE "active" = ?';
        $results = $this->_adaptor->fetchAll($sql, array('Y'));
        $tmp = array();
        if (is_array($results)) {
            foreach ($results as $result) {
                $tmp[$result['key']] = $result['id'];
            }
        }
        return $tmp;

    }// end getAllSites

}// end Dao_Oxi
?>